import { createApp, createVNode } from 'vue'
import App from './App.vue'

// 引入elementPlus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

// 引入router
import router from './router/index'

// 引入vuex
import { store, key } from './store/index'

// 引入图标
import * as Icons from '@element-plus/icons-vue'

import { getToken, cleanSession } from './utils/auth'

// 引入工具类
import myConfirm from './utils/myconfirm'
import objCopy from './utils/objCopy'
import restForm from './utils/restForm'

// 解决分页英文的问题
import locale from 'element-plus/lib/locale/lang/zh-cn' 

// 引入按钮权限
import { permission } from './directives/permission'

// 引入echarts
import * as echarts from 'echarts'

import quanju from '@/components/quanju.vue'

// createApp(App).use(router).use(store, key).use(ElementPlus,{locale}).mount('#app') // 简写版
const app = createApp(App)
app.use(router)
app.use(store, key) // 传入 injection key
// app.use(ElementPlus)
app.use(ElementPlus,{locale})
app.directive('permission', permission)
// 注册全局组件
app.component('quanju', quanju) // .component('quanju',quanju)就是注册全局组件 （‘自定义键名’，组件名）
app.mount('#app')

// 挂载工具
app.config.globalProperties.$myConfirm = myConfirm
app.config.globalProperties.$objCopy = objCopy
app.config.globalProperties.$restForm = restForm

// 挂载echart
app.config.globalProperties.$echarts = echarts


// 方式一:
// typeof 和 keyof
// const person = {
//     name: '张三',
//     age: 18
// }
// typeof获取一个对象的类型
// type tp = typeof person
// keyof获取某种类型的所有键(key),返回的类型是一个联合类型
// type keys = keyof typeof person

// 全局注册组件
Object.keys(Icons).forEach((key) => {
    app.component(key, Icons[key as keyof typeof Icons])
})

// 这么写也可以
// Object.keys(Icons).forEach((key) => {
//     console.log(key)
//     app.component(key, Icons[key])
// })

// 方式二：
// const Icon = (props: {icon:string}) => {
//     const { icon } = props
//     return createVNode(Icons[icon as keyof typeof Icons])
// }
// app.component('Icon', Icon)

// 权限验证的处理 全局守卫路由实现
// 白名单 放行
const whiteList = ['/login']
router.beforeEach(async(to,from,next) => {
    // 获取token
    let token = getToken()
    if(token){
        if(to.path === '/login' || to.path === '/') {
            next({path: '/'})
        } else {
            // 从vuex里获取菜单
            let hasRoles = store.state.user.permission && store.state.user.permission.length > 0
            if(hasRoles) {
                next()
            } else {
                try {
                    // vuex中不存在权限,从服务器中获取
                    await store.dispatch('user/getInfo')
                    // 获取菜单,动态生成路由
                    await store.dispatch('menu/getMenuList', router)
                    // 确保动态添加的路由已经被完全加载上去
                    next({...to,replace:true})
                } catch (error) {
                    // 重置token
                    cleanSession()
                    // 跳到登录
                    next({path:'/login'})
                }
            }
        }
    } else {
        // 判断是否在白名单中
        if(whiteList.indexOf(to.path) !== -1) {
            // 如果存在白名单中，直接放行
            next()
        } else {
            // 如果不存在，重定向到登录页面
            next({path:'/login'})
        }
    }
})